#include "Defs.h"
#include "RuleTokens.h"


//
// constructors and destructors
//

RuleTokens_T::RuleTokens_T(const char * szName, const char * szRootSection, const char * szConfigFile)
	: flag(false)
{
	FillMemory(_szName, sizeof(_szName), 0);
	_snprintf(_szName, sizeof(_szName) - 1, szName);

	FillMemory(_szOtherName, sizeof(_szOtherName), 0);

	flag = GetPrivateProfileInt(szRootSection, _szName, 1, szConfigFile) == 1;
	if( flag )
	{
		Load(_szName, szConfigFile);
	}
}

RuleTokens_T::RuleTokens_T(const char * szName, const char * szOtherName, const char * szRootSection, const char * szConfigFile)
	: flag(false)
{
	FillMemory(_szName, sizeof(_szName), 0);
	_snprintf(_szName, sizeof(_szName) - 1, szName);

	FillMemory(_szOtherName, sizeof(_szOtherName), 0);
	_snprintf(_szOtherName, sizeof(_szOtherName) - 1, szOtherName);

	flag = GetPrivateProfileInt(szRootSection, _szName, 1, szConfigFile) == 1;
	Load(flag ? _szName : _szOtherName, szConfigFile);
}

void RuleTokens_T::ToString(char * szBuffer, unsigned int bufferSize)
{
	char szText[MAX_PATH];
	unsigned int bufferCursor = 0;

	if( (lstrlen(_szOtherName) > 0) || flag )
	{
		if( lstrlen(_szOtherName) > 0 )
		{
			_snprintf(szBuffer + bufferCursor, bufferSize - 1 - bufferCursor, 
				"# [%s]\r\n", flag ? _szName : _szOtherName);
		}
		else
		{
			_snprintf(szBuffer + bufferCursor, bufferSize - 1 - bufferCursor, 
				"# [%s]\r\n", _szName);
		}

		bufferCursor = lstrlen(szBuffer);
	}

	for( unsigned int ix = 0 ; ix < tokenList.Count() ; ix++ )
	{
		FillMemory(szText, sizeof(szText), 0);
		_snprintf(szBuffer + bufferCursor, bufferSize - 1 - bufferCursor,
			"# \t%s\r\n", tokenList[ix]->ToString(szText, sizeof(szText)));

		bufferCursor = lstrlen(szBuffer);
	}
}

//
// private members
//

void RuleTokens_T::Load(const char * szName, const char * szConfigFile)
{
	sectionData.Create(File_T::GetSize(szConfigFile));
	GetPrivateProfileSection(
		szName,
		(char *)sectionData.Ptr(),
		sectionData.Max(),
		szConfigFile);

	// 
	// Browse through the several entries
	//

	char * szLine = (char *)sectionData.Ptr();
	while( *szLine != '\0' )
	{
		int lineLength = lstrlen(szLine);
		int parseLength = lineLength;

		// 
		// Parse the hexadecimal entries
		//
	
		for( int ix = 0 ; ix < (parseLength - 3) ; )
		{
			if( (szLine[ix] == '\\') &&
				(
					(szLine[ix + 1] == 'x') || 
					(szLine[ix + 1] == 'X')
				) &&
				(
					((szLine[ix + 2] >= 'a') && (szLine[ix + 2] <= 'f')) ||
					((szLine[ix + 2] >= 'A') && (szLine[ix + 2] <= 'F')) ||
					((szLine[ix + 2] >= '0') && (szLine[ix + 2] <= '9'))
				) &&
				(
					((szLine[ix + 3] >= 'a') && (szLine[ix + 3] <= 'f')) ||
					((szLine[ix + 3] >= 'A') && (szLine[ix + 3] <= 'F')) || 
					((szLine[ix + 3] >= '0') && (szLine[ix + 3] <= '9'))
				) )
			{
				char hexString[3];

				hexString[0] = szLine[ix + 2];
				hexString[1] = szLine[ix + 3];
				szLine[ix] = (unsigned char)strtol(hexString, NULL, 16);

				if( ix + 4 < parseLength )
				{
					RtlMoveMemory(szLine + ix + 1, szLine + ix + 4, parseLength - 4 - ix);
				}
				parseLength -= 3;
			}
			ix++;
		}

		tokenList.Add(new Buffer_T((unsigned char *)szLine, parseLength));
		szLine += lineLength + 1;
	}
}
